home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 9 / Example 9.1 / unit.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-07-15  |  6.0 KB  |  252 lines

  1. #include "unit.h"
  2.  
  3. std::vector<SKINNEDMESH*> unitMeshes;
  4.  
  5. void LoadUnitResources(IDirect3DDevice9* Device)
  6. {
  7.     std::vector<std::string> fnames;
  8.  
  9.     fnames.push_back("units/drone.x");
  10.     fnames.push_back("units/soldier.x");
  11.     fnames.push_back("units/magician.x");
  12.  
  13.     for(int i=0;i<fnames.size();i++)
  14.     {
  15.         SKINNEDMESH *newMesh = new SKINNEDMESH();
  16.         newMesh->Load((char*)fnames[i].c_str(), Device);
  17.         unitMeshes.push_back(newMesh);
  18.     }
  19. }
  20.  
  21. void UnloadUnitResources()
  22. {
  23.     for(int i=0;i<unitMeshes.size();i++)
  24.         if(unitMeshes[i] != NULL)
  25.             delete unitMeshes[i];
  26.  
  27.     unitMeshes.clear();
  28. }
  29.  
  30. //////////////////////////////////////////////////////////////////////////////////
  31. //                                UNIT                                            //
  32. //////////////////////////////////////////////////////////////////////////////////
  33.  
  34. UNIT::UNIT(int _type, int _team, INTPOINT mp, TERRAIN *_terrain, IDirect3DDevice9* Dev) : MAPOBJECT()
  35. {
  36.     m_type = _type;
  37.     m_team = _team;
  38.     m_mappos = mp;
  39.     m_pTerrain = _terrain;
  40.     m_pDevice = Dev;
  41.     m_mapsize.Set(1, 1);
  42.     m_time = 0.0f;
  43.     m_animation = m_activeWP = 0;
  44.     m_rotation = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  45.     m_scale = D3DXVECTOR3(0.2f, 0.2f, 0.2f);
  46.     m_isBuilding = m_moving = false;
  47.     m_movePrc = 0.0f;
  48.  
  49.     if(m_pTerrain != NULL)
  50.         m_position = m_pTerrain->GetWorldPos(m_mappos);
  51.     else m_position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  52.  
  53.     if(m_type == 0)        //Farmer
  54.     {
  55.         m_hp = m_hpMax = 100;
  56.         m_range = 1;
  57.         m_damage = 5;
  58.         m_sightRadius = 7;
  59.         m_speed = 1.0f;
  60.         m_name = "Farmer";
  61.     }    
  62.     else if(m_type == 1)        //Soldier
  63.     {
  64.         m_hp = m_hpMax = 180;
  65.         m_range = 1;
  66.         m_damage = 12;
  67.         m_sightRadius = 8;
  68.         m_speed = 0.8f;
  69.         m_name = "Soldier";
  70.     }    
  71.     else if(m_type == 2)        //Magician
  72.     {
  73.         m_hp = m_hpMax = 100;
  74.         m_range = 5;
  75.         m_damage = 8;
  76.         m_sightRadius = 10;
  77.         m_speed = 1.1f;
  78.         m_name = "Magician";
  79.     }    
  80.  
  81.     m_pAnimControl = unitMeshes[m_type]->GetAnimationControl();
  82.     if(m_pAnimControl != NULL)
  83.         m_pAnimControl->ResetTime();
  84.  
  85.     SetAnimation("Still");
  86. }
  87.  
  88. UNIT::~UNIT()
  89. {
  90.  
  91. }
  92.  
  93. void UNIT::Render()
  94. {
  95.     if(m_type < unitMeshes.size() && unitMeshes[m_type] != NULL)
  96.     {
  97.         SetAnimation(m_animation);
  98.  
  99.         unitMeshes[m_type]->SetPose(GetWorldMatrix(), m_pAnimControl, m_time);
  100.         unitMeshes[m_type]->Render(NULL);
  101.         m_time = 0.0f;
  102.     }
  103. }
  104.  
  105. void UNIT::Update(float deltaTime)
  106. {
  107.     //update unit animation time
  108.     m_time += deltaTime * 0.8f * m_speed;
  109.  
  110.     //if the unit is moving...
  111.     if(m_moving)
  112.     {
  113.         if(m_movePrc < 1.0f)m_movePrc += deltaTime * m_speed;
  114.         if(m_movePrc > 1.0f)m_movePrc = 1.0f;
  115.         
  116.         //waypoint reached
  117.         if(m_movePrc == 1.0f)
  118.         {
  119.             if(m_activeWP + 1 >= m_path.size())        //goal reached
  120.             {
  121.                 m_moving = false;
  122.                 SetAnimation("Still");
  123.             }
  124.             else if(!CheckCollision(m_path[m_activeWP + 1])) //Next Waypoint
  125.             {            
  126.                 m_activeWP++;
  127.                 SetAnimation("Run");
  128.                 MoveUnit(m_path[m_activeWP]);
  129.             }
  130.         }
  131.  
  132.         //Interpolate position between m_lastWP and m_nextWP
  133.         m_position = m_lastWP * (1.0f - m_movePrc) + m_nextWP * m_movePrc;
  134.     }
  135. }
  136.  
  137. bool UNIT::CheckCollision(INTPOINT mp)
  138. {    
  139.     return false;        //No Collision
  140. }
  141.  
  142. void UNIT::Goto(INTPOINT mp)
  143. {
  144.     if(m_pTerrain == NULL)return;
  145.  
  146.     //Clear old path
  147.     m_path.clear();
  148.     m_activeWP = 0;
  149.  
  150.     if(m_moving)        //If unit is currently moving
  151.     {
  152.         //Finish the active waypoint 
  153.         m_path.push_back(m_mappos);
  154.         std::vector<INTPOINT> tmpPath = m_pTerrain->GetPath(m_mappos, mp);
  155.  
  156.         //add new path
  157.         for(int i=0;i<tmpPath.size();i++)
  158.             m_path.push_back(tmpPath[i]);
  159.     }
  160.     else        //Create new path from scratch...
  161.     {
  162.         m_path = m_pTerrain->GetPath(m_mappos, mp);
  163.         
  164.         if(m_path.size() > 0)        //if a path was found
  165.         {
  166.             m_moving = true;
  167.  
  168.             //Check that the next tile is free
  169.             if(!CheckCollision(m_path[m_activeWP]))
  170.             {
  171.                 MoveUnit(m_path[m_activeWP]);
  172.                 SetAnimation("Run");                
  173.             }
  174.         }
  175.     }
  176. }
  177.  
  178. void UNIT::MoveUnit(INTPOINT to)
  179. {
  180.     m_lastWP = m_pTerrain->GetWorldPos(m_mappos);
  181.     m_rotation = GetDirection(m_mappos, to);
  182.  
  183.     m_mappos = to;        //New mappos
  184.     m_movePrc = 0.0f;
  185.     m_nextWP = m_pTerrain->GetWorldPos(m_mappos);
  186. }
  187.  
  188. BBOX UNIT::GetBoundingBox()
  189. {
  190.     if(m_type == 0)            //Farmer
  191.         return BBOX(m_position + D3DXVECTOR3(0.3f, 1.0f, 0.3f), m_position - D3DXVECTOR3(0.3f, 0.0f, 0.3f));
  192.     else if(m_type == 1)    //Soldier
  193.         return BBOX(m_position + D3DXVECTOR3(0.35f, 1.2f, 0.35f), m_position - D3DXVECTOR3(0.35f, 0.0f, 0.35f));
  194.     else if(m_type == 2)    //Magician
  195.         return BBOX(m_position + D3DXVECTOR3(0.3f, 1.1f, 0.3f), m_position - D3DXVECTOR3(0.3f, 0.0f, 0.3f));
  196. }
  197.  
  198. D3DXMATRIX UNIT::GetWorldMatrix()
  199. {
  200.     D3DXMATRIX s, p, r;
  201.     D3DXMatrixTranslation(&p, m_position.x, m_position.y, m_position.z);
  202.     D3DXMatrixRotationYawPitchRoll(&r, m_rotation.y, m_rotation.x, m_rotation.z);
  203.     D3DXMatrixScaling(&s, m_scale.y, m_scale.x, m_scale.z);
  204.     return s * r * p;
  205. }
  206.  
  207. D3DXVECTOR3 UNIT::GetDirection(INTPOINT p1, INTPOINT p2)
  208. {
  209.     int dx = p2.x - p1.x, dy = p2.y - p1.y;
  210.     
  211.     if(dx < 0 && dy > 0)    return D3DXVECTOR3(0.0f, D3DX_PI/4,        0.0f); 
  212.     if(dx == 0 && dy > 0)    return D3DXVECTOR3(0.0f, 0.0f,            0.0f);
  213.     if(dx > 0 && dy > 0)    return D3DXVECTOR3(0.0f, -D3DX_PI/4,    0.0f); 
  214.     if(dx > 0 && dy == 0)    return D3DXVECTOR3(0.0f, -D3DX_PI/2,    0.0f);
  215.     if(dx > 0 && dy < 0)    return D3DXVECTOR3(0.0f, (-D3DX_PI/4)*3,0.0f); 
  216.     if(dx == 0 && dy < 0)    return D3DXVECTOR3(0.0f, D3DX_PI,        0.0f);
  217.     if(dx < 0 && dy < 0)    return D3DXVECTOR3(0.0f, (D3DX_PI/4)*3,    0.0f); 
  218.     if(dx < 0 && dy == 0)    return D3DXVECTOR3(0.0f, D3DX_PI/2,        0.0f);
  219.  
  220.     return m_rotation;
  221. }
  222.  
  223. void UNIT::SetAnimation(char name[])
  224. {
  225.     ID3DXAnimationSet *anim = NULL;
  226.     m_animation = 0;
  227.  
  228.     for(int i=0;i<m_pAnimControl->GetMaxNumAnimationSets();i++)
  229.     {
  230.         anim = NULL;
  231.         m_pAnimControl->GetAnimationSet(i, &anim);
  232.  
  233.         if(anim != NULL)
  234.         {
  235.             if(strcmp(name, anim->GetName()) == 0)
  236.             {
  237.                 m_pAnimControl->ResetTime();
  238.                 m_pAnimControl->SetTrackAnimationSet(0, anim);
  239.                 m_animation = i;
  240.             }
  241.             anim->Release();
  242.         }
  243.     }
  244. }
  245.  
  246. void UNIT::SetAnimation(int index)
  247. {
  248.     ID3DXAnimationSet *anim = NULL;
  249.     m_pAnimControl->GetAnimationSet(index, &anim);
  250.     if(anim != NULL)m_pAnimControl->SetTrackAnimationSet(0, anim);
  251.     anim->Release();
  252. }